---
title: GetUserLastLogon
summary: Derives a user's last logon timestamp from the lastLogonTimestamp FILETIME attribute.
status: draft
owner: "Not determined from source"
last_reviewed: 2026-09-22
---

# GetUserLastLogon (OP-16)

## Request and response

| Part | Type | Description |
| --- | --- | --- |
| `inUserId` | `String` | The `SamAccountName` to look up. |
| `inExternalDomain` | `Boolean` | Selects `external.saif.com` when `True`, `corp.saif.com` when `False` ([BR-07](../business-rules.md#br-07-the-directory-domain-is-selected-by-the-caller)). |

| Part | Type | Description |
| --- | --- | --- |
| `<return>` | `ADServiceResponse` | `Response` (`EResponse` code) and `Message` (the rendered last-logon date-time string on success). |

## WebMethod attributes

`<WebMethod()>` — bare, no arguments supplied.

## Steps

1. No access check is performed ([BR-06](../business-rules.md#br-06-read-only-directory-queries-are-not-access-controlled)).
2. Initialize `myStruc.Response = Success`, `myStruc.Message = String.Empty`.
3. In a `Try` block, call H2 `GetUserPrincipal` with the caller-supplied `inExternalDomain`.
4. If the principal is `Nothing`, set `Response = UserDoesNotExist`.
5. Otherwise, get the underlying `DirectoryEntry` and compose the 64-bit FILETIME as `lastLogonTimestamp(0).HighPart * 4294967296 + lastLogonTimestamp(0).lowpart` into a `Decimal`, via late-bound COM property access ([BR-30](../business-rules.md#br-30-last-logon-is-derived-from-the-filetime-attribute)).
6. If the composed value is less than 1, set `Response = InfoNotAvailable`. (An authored comment reads "let's assume they logged in Jan 1, 2000", but no such date is actually applied — only the `InfoNotAvailable` code is returned.)
7. Otherwise, divide by `60 * 10000000` to obtain minutes and set `Message = DateAdd(DateInterval.Minute, lastLogon, #1/1/1601#).ToString` ([BR-30](../business-rules.md#br-30-last-logon-is-derived-from-the-filetime-attribute)).
8. `Catch`: set `Response = Failure`, `Message = ex.Message`.
9. `Finally`: release `userPrin` and `de`.
10. Return the `ADServiceResponse` sentinel.

A user with no `lastLogonTimestamp` attribute yields `Failure` with a .NET exception message rather than `InfoNotAvailable`*. The rendered timestamp uses the server's current culture and time zone, which is environment-dependent*.

## Process flow

```mermaid
flowchart TD
    A["Call GetUserLastLogon"] --> B["GetUserPrincipal<br>caller-selected domain"]
    B -->|"Nothing"| C["Response = UserDoesNotExist"]
    B -->|"Found"| D["Compose FILETIME<br>HighPart * 4294967296 + lowPart"]
    D --> E{"Value < 1?"}
    E -->|"Yes"| F["Response = InfoNotAvailable"]
    E -->|"No"| G["Divide by 60 * 10000000<br>DateAdd from 1/1/1601"]
    G --> H["Message = rendered timestamp<br>Response = Success"]
    D -->|"Exception"| I["Response = Failure<br>Message = ex.Message"]
    C --> J["Return ADServiceResponse"]
    F --> J
    H --> J
    I --> J
```

## Shared state effects

None — this operation touches no process-wide state; all locals are per-request.

## Error handling

This operation never faults: every failure path — an unresolved user, an unset `lastLogonTimestamp` attribute, or any other directory exception — is caught and mapped to `Response = Failure` with `ex.Message` in `Message`. See [Faults](../faults.md) for the service-wide fault model.

## Authorization

None in code. This is one of the eleven ungated operations that disclose directory data to any caller who can reach the endpoint (see [Authentication and authorization](../authentication-authorization.md) and [Tech debt](../tech-debt.md)).

## Related documentation
- [Service index](../index.md)
- [Overview](../overview.md)
- [Architecture](../architecture.md)
- [Activation and hosting](../activation-hosting.md)
- [Operations](../operations.md)
- [Operations and processes](../operations-processes.md)
- [Business rules](../business-rules.md)
- [Authentication and authorization](../authentication-authorization.md)
- [Configuration](../configuration.md)
- [Dependencies](../dependencies.md)
- [Faults](../faults.md)
- [Operational runbook](../operational-runbook.md)
- [Tech debt](../tech-debt.md)

> **Note:** Statements marked with * were inferred from code structure, naming conventions, or
> contextual evidence where direct confirmation was not available in source artifacts. Statements
> marked with ** could not be confirmed; treat as unknown until verified.

## Sources
- `src\ADUserServices\clsADUserServices.asmx.vb` (lines 649-685)
